package JZ_Offer.algorithm.模拟;

/**
 * 表示数值的字符串
 *
 * 请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。
 * 例如，字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
 */
public class JZ20_表示数值的字符串 {

    /**
     * 链接：https://www.nowcoder.com/questionTerminal/6f8c901d091949a5837e24bb82a731f2?answerType=1&f=discussion
     * 来源：牛客网
     */
    private static boolean isNumeric(char[] str) {
        if (str[0] == '+' || str[0] == '-') {
            return helper(str, 1, false, false);
        }
        return helper(str, 0, false, false);
    }

    // 第一个可以是 + -，如果后面在遇到直接跳过
    // 除了数字和 e . 之外返回失败
    private static boolean helper(char[] str, int index, boolean e, boolean point) {
        if (index > str.length) {
            return false;
        }
        if (index == str.length) {
            return true;
        }

        char c = str[index];
        if (c >= '0' && c <= '9') {
            return helper(str, index + 1, e, point);
        } else if (c == 'e' || c == 'E' || c == '.') {
            if (c == 'e' || c == 'E') {
                e = true;
            }

            // 小数点出现过了，又遇到e或E肯定错 124e+1.2算错
            if (c == '.' && e) {
                return false;
            }

            if (c == '.') {
                if (point) {
                    return false;
                }
                point = true;
                return helper(str, index + 1, e, point);
            }

            if (index + 1 >= str.length) {
                return false;
            } else {
                char nc = str[index + 1];
                if (nc == '+' || nc == '-') {
                    return helper(str, index + 2, e, point);
                } else {
                    return helper(str, index + 1, e, point);
                }
            }
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        char[] str = {'3', '.', '1', '4', '1', '6'};
        char[] str1 = {'-', '1', '4', '1', '6'};
        char[] str2 = {'1', 'e', '1', '6'};
        char[] str3 = {'-', '.', '1', '6'};
        char[] str4 = {'1', 'a', '3', '.', '1', '6'};
        char[] str5 = {'-', '1', '+', 'e', '1'};
        boolean b = isNumeric(str5);
        System.out.println(b);
    }
}
